package com.hw.protocol.tool.decode.hw;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.hw.protocol.tool.config.DevExceptionEnum;
import com.hw.protocol.tool.model.entity.MeterData;
import com.hw.protocol.tool.model.entity.hw.*;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * @author : lihy
 * @date : 2023/8/14 14:46
 * description: 昊威协议数据转换
 */
public class HwTransformUtil {

    /**
     * 流量计数据转换为实时数据
     *
     * @param flowMeter 流量计数据
     * @return 实时数据
     */
    public static MeterData transform(AbsFlowMeter flowMeter) {
        MeterData md = getMeterData(flowMeter.getDevSerial(), flowMeter.getChunnelSerial());
        md.setData1((double) flowMeter.getTemperature());
        md.setData2((double) flowMeter.getPress());
        md.setData3((double) flowMeter.getFlux());
        md.setData4((double) flowMeter.getRealFlux());
        md.setData11((double) flowMeter.getFlag()[1] / 10);
        md.setData12((double) flowMeter.getFlag()[2]);
        String alarmMsg = "";
        if (flowMeter.getMeterType() == 0) {
            //未读到数据
            alarmMsg = DevExceptionEnum.UNREAD_DATA.getCode() + ";";
        }
        if (((int) flowMeter.getFlag()[0] & 0b11) == 1) {
            //阀门关
            alarmMsg = +DevExceptionEnum.VALVE_CLOSE.getCode() + ";";
        }
        if (((int) flowMeter.getFlag()[0] & 0b11) == 3) {
            //阀门异常
            alarmMsg = DevExceptionEnum.VALVE_EXCEPTION.getCode() + ";";
        }
        if (((int) flowMeter.getFlag()[0] >> 2 & 0b01) == 1) {
            //修正仪电压低
            alarmMsg = DevExceptionEnum.CORRECTOR_VOLTAGE_LOWER.getCode() + ";";
        }
        if (flowMeter instanceof Dtu50) {
            Dtu50 dtu50 = (Dtu50) flowMeter;
            md.setData5(dtu50.getVolume());
            md.setData6(dtu50.getRealVolume());
            md.setData9((double) dtu50.getRatio());
            md.setData10((double) dtu50.getFactor());
            if (((int) flowMeter.getFlag()[0] >> 3 & 0b01) == 1) {
                //设备外供电中断
                alarmMsg = DevExceptionEnum.EQUIPMENT_ELEMENT_CLOSED.getCode() + "";
            }
            md.setAlarmMsg(alarmMsg);
            if (flowMeter instanceof Dtu50His) {
                md.setHistory(true);
                md.setWriteTime(DateTime.of(((Dtu50His) flowMeter).getTime(), DatePattern.NORM_DATETIME_PATTERN));
            } else {
                md.setWriteTime(new Date());
            }
        }
        if (flowMeter instanceof Dtu61) {
            Dtu61 dtu61 = (Dtu61) flowMeter;
            md.setData5(dtu61.getVolume());
            md.setData6(dtu61.getRealVolume());
            md.setData11(((double) flowMeter.getFlag()[1]) / 10);
            if (((int) flowMeter.getFlag()[0] >> 3 & 0b01) == 1) {
                //设备电池电压不足
                alarmMsg = DevExceptionEnum.EQUIPMENT_BATTERY_LOWER.getCode() + "";
            }
            if (flowMeter.getFlag()[3] != 0) {
                //修正仪表异常
                alarmMsg = DevExceptionEnum.CORRECTOR_METER_ANOMALY.getCode() + "";
            }
            md.setAlarmMsg(alarmMsg);
            if (flowMeter instanceof Dtu61His) {
                md.setHistory(true);
                md.setWriteTime(DateTime.of(((Dtu61His) flowMeter).getTime(), DatePattern.NORM_DATETIME_PATTERN));
            } else {
                md.setWriteTime(new Date());
            }
        }
        return md;
    }

    /**
     * 压力计数据转换为实时数据
     *
     * @param pressMeter 压力计数据
     * @return 实时数据
     */
    public static List<MeterData> transform(AbsPressMeter pressMeter) {
        List<MeterData> list = new LinkedList<>();
        if (pressMeter instanceof Dtu60) {
            Dtu60 dtu60 = (Dtu60) pressMeter;
            //泄漏报警
            MeterData md = getMeterData(pressMeter.getDevSerial(), "3000");
            md.setData1((double) dtu60.getAlarm());
            setFlagAndTime(pressMeter, md);
            list.add(md);
            //第一路压力
            MeterData mdPress = getMeterData(pressMeter.getDevSerial(), "3001");
            mdPress.setData2((double) dtu60.getPress1());
            setFlagAndTime(pressMeter, md);
            list.add(mdPress);
            //第二路压力
            MeterData mdPress2 = getMeterData(pressMeter.getDevSerial(), "3002");
            mdPress2.setData2((double) dtu60.getPress2());
            setFlagAndTime(pressMeter, md);
            list.add(mdPress2);
        }
        return list;
    }

    /**
     * 智能调压箱数据转换为实时数据
     *
     * @param box 调压箱数据
     * @return 实时数据
     */
    public static MeterData transform(RegulatorBox box) {
        MeterData md = getMeterData(box.getChunnelSerial(), box.getDevSerial());
        md.setData1((double) box.getInPress());
        md.setData2((double) box.getOutPress());
        md.setData3((double) box.getTemperature());
        md.setData4((double) box.getDifferentialPressure1());
        md.setData5((double) box.getDifferentialPressure2());
        md.setData6((double) box.getValveOpening1());
        md.setData7((double) box.getValveOpening2());
        md.setData8((double) box.getValveSsv1());
        md.setData9((double) box.getValveSsv2());
        md.setData10((double) box.getLeakage());
        md.setData11((double) box.getFlag()[1] / 10);
        md.setData12((double) box.getFlag()[2]);
        md.setData15((double) box.getDoorSignal1());
        md.setData16((double) box.getDoorSignal1());

        if (box instanceof RegulatorBoxHis) {
            md.setHistory(true);
            md.setWriteTime(DateTime.of(((RegulatorBoxHis) box).getTime(), DatePattern.NORM_DATETIME_PATTERN));
        } else {
            String alarmMsg = "";
            if (box.getMeterType() == 0) {
                //未读到数据
                alarmMsg = DevExceptionEnum.UNREAD_DATA.getCode() + ";";
            }
            if (((int) box.getFlag()[0] >> 3 & 0x01) == 1) {
                alarmMsg = DevExceptionEnum.EQUIPMENT_BATTERY_LOWER.getCode() + "";
            }
            md.setAlarmMsg(alarmMsg);
            md.setWriteTime(new Date());
        }
        return md;
    }

    /**
     * 商业报警器数据转换
     *
     * @param alertor 报警器数据
     * @return 实时数据
     */
    public static List<MeterData> transform(Alertor alertor) {
        boolean his = false;
        String alarmMsg = "";
        if (alertor instanceof AlertorHis) {
            his = true;
        } else {
            if (((int) alertor.getFlag()[0] >> 3 & 0x01) == 1) {
                alarmMsg = DevExceptionEnum.EQUIPMENT_BATTERY_LOWER.getCode() + ",";
            }
        }
        List<MeterData> list = new LinkedList<>();
        for (int i = 0; i < alertor.getAlerts().length; i++) {
            AlertorData alert = alertor.getAlerts()[i];
            if (alert.getSenser() == 0) {
                continue;
            }
            MeterData md = new MeterData();
            md.setDevSerial(alertor.getDevSerial());
            md.setChunnelSerial(Integer.parseInt(alertor.getChunnelSerial() + 1 + i) + "");
            md.setData1((double) alert.getData());
            md.setData11((double) alertor.getFlag()[1] / 10);
            md.setData12((double) alertor.getFlag()[2]);
            if (his) {
                md.setWriteTime(DateTime.of(((AlertorHis) alertor).getTime(), DatePattern.NORM_DATETIME_PATTERN));
                md.setHistory(true);
            } else {
                md.setWriteTime(new Date());
                if (((int) alert.getStatus() & 0x01) == 1) {
                    alarmMsg += DevExceptionEnum.HARD_WARE_ERROR.getCode() + ",";
                }
                if (((int) alert.getStatus()>>1 & 0x01) == 1) {
                    alarmMsg += DevExceptionEnum.LOW_ALERT.getCode() + ",";
                }
                if (((int) alert.getStatus()>>2 & 0x01) == 1) {
                    alarmMsg += DevExceptionEnum.HIGH_ALERT.getCode();
                }

                md.setAlarmMsg(alarmMsg);

            }
            list.add(md);
        }
        return list;
    }

    /**
     * 设置电压、信号、采集时间
     *
     * @param pressMeter 压力计数据
     * @param md         实时数据
     */
    private static void setFlagAndTime(AbsPressMeter pressMeter, MeterData md) {
        md.setData11(((double) pressMeter.getFlag()[1]) / 10);
        md.setData12((double) pressMeter.getFlag()[2]);
        getHistory(pressMeter, md);
    }

    /**
     * 获取历史数据
     *
     * @param pressMeter 转换前数据
     * @param md         转换后数据
     */
    private static void getHistory(AbsPressMeter pressMeter, MeterData md) {
        if (pressMeter instanceof Dtu60His) {
            md.setHistory(true);
            md.setWriteTime(DateUtil.parseDateTime(((Dtu60His) pressMeter).getTime()));
        } else {
            md.setWriteTime(new Date());
        }
    }

    /**
     * 创建实时数据
     *
     * @param devSerial     设备编号
     * @param chunnelSerial 通道号
     * @return 实时数据
     */
    private static MeterData getMeterData(String devSerial, String chunnelSerial) {
        MeterData md = new MeterData();
        md.setDevSerial(devSerial);
        md.setChunnelSerial(chunnelSerial);
        return md;
    }



}
